//! Time-related system calls
//! SPDX-License-Identifier: MPL-2.0

const std = @import("std");
const SyscallReturn = @import("../return.zig").SyscallReturn;
const SyscallError = @import("../error.zig").SyscallError;
const Context = @import("../context.zig").Context;
const VirtAddr = @import("../context.zig").VirtAddr;

/// Time structure
pub const TimeVal = extern struct {
    tv_sec: i64,
    tv_usec: i64,
};

/// Timespec structure
pub const TimeSpec = extern struct {
    tv_sec: i64,
    tv_nsec: i64,
};

/// Get current time
pub fn sys_gettimeofday(tv: VirtAddr, tz: VirtAddr, ctx: *Context) SyscallReturn {
    _ = tz; // timezone is deprecated
    
    if (tv != 0) {
        const user_space = ctx.user_space();
        
        // Get current time (placeholder implementation)
        const current_time = TimeVal{
            .tv_sec = std.time.timestamp(),
            .tv_usec = 0, // TODO: Get microseconds
        };
        
        // Write to user space
        const bytes = std.mem.asBytes(&current_time);
        _ = user_space.write_bytes(tv, bytes) catch {
            return SyscallReturn.error_return(SyscallError.EFAULT);
        };
    }
    
    return SyscallReturn.success(0);
}

/// Get time in seconds since epoch
pub fn sys_time(tloc: VirtAddr, ctx: *Context) SyscallReturn {
    const current_time = std.time.timestamp();
    
    if (tloc != 0) {
        const user_space = ctx.user_space();
        const time_bytes = std.mem.asBytes(&current_time);
        _ = user_space.write_bytes(tloc, time_bytes) catch {
            return SyscallReturn.error_return(SyscallError.EFAULT);
        };
    }
    
    return SyscallReturn.success(@intCast(current_time));
}

/// Sleep for specified time
pub fn sys_nanosleep(req: VirtAddr, rem: VirtAddr, ctx: *Context) SyscallReturn {
    _ = req;
    _ = rem;
    _ = ctx;
    // TODO: Implement nanosleep
    // This would involve:
    // 1. Reading timespec from user space
    // 2. Setting up timer
    // 3. Blocking current thread
    // 4. Handling interruptions
    return SyscallReturn.error_return(SyscallError.ENOSYS);
}